#ifndef _X_MYSQL_CONNECT_POOL_H
#define _x_MYSQL_CONNECT_POOL_H
#include "x_mysql.h"
#include <deque>
#include <vector>
#include <mutex>
#include <map>
#include <condition_variable>
#include "vector"
namespace x_3rd
{
    class x_mysql_connect_pool{
        public:
            x_mysql_connect_pool(uint16_t cons_size = 1):m_cons_size(cons_size){}
            ~x_mysql_connect_pool()
            {
                for(int i=0;i<m_all_cons.size();i++)
                {
                    delete m_all_cons[i];
                    m_all_cons[i] = nullptr;
                }
                m_all_cons.clear();
                m_que_cons.clear();
            }
        public:
            void init(uint16_t cons_size = 1)
            {
                m_cons_size = cons_size;
                for(int i=0;i<m_cons_size;i++)
                {
                    x_mysql* con = new x_mysql();
                    m_all_cons.push_back(con);
                    m_que_cons.push_back(con);
                }
            }
            x_mysql* get_con()
            {
                std::unique_lock<std::mutex> guard(m_gs_mutex);
                m_gs_condit.wait(guard,[this](){
                    return !m_que_cons.empty();
                });
                x_mysql* con = m_que_cons.front();
                m_que_cons.pop_front();
                return con;
            }
            void put_con(x_mysql* con)
            {
                std::unique_lock<std::mutex> guard(m_gs_mutex);
                m_que_cons.push_back(con);
                m_gs_condit.notify_one();
            }
        private:
            std::mutex              m_gs_mutex;
            std::condition_variable m_gs_condit;
            uint16_t                m_cons_size;
            std::vector<x_mysql*>   m_all_cons;
            std::deque<x_mysql*>    m_que_cons;
    };

    enum DB_TYPE{
        GAME_DB,
        LOGIN_DB,
        GATE_DB
    };

    class x_shared_db{
        public:
            x_shared_db& instance()
            {
                static x_shared_db db;
                return db;
            }
            ~x_shared_db()
            {
                for(auto it=m_shared_db.begin();it!=m_shared_db.end();it++)
                {
                    if(it->second)
                    {
                        delete it->second;
                        it->second = nullptr;
                    }
                }
                m_shared_db.clear();
            }
            x_mysql_connect_pool* get(DB_TYPE type)
            {
                auto it = m_shared_db.find(type);
                if(it == m_shared_db.end())
                {
                    m_shared_db[type] = new x_mysql_connect_pool();
                    return m_shared_db[type];
                }
                return m_shared_db[type];
            }
        private:
            std::map<uint32_t,x_mysql_connect_pool*> m_shared_db;
    };
}
#endif 